package com.github.fashionbrot.util;

import com.github.fashionbrot.common.cookie.ResponseCookie;
import com.github.fashionbrot.common.util.ObjectUtil;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * Cookie 工具类，提供新增和删除Cookie的功能
 */
public class CookieUtil {

    // 禁用构造函数
    private CookieUtil() {
        throw new IllegalStateException("工具类不允许实例化");
    }


    /**
     * 增加cookie
     * @param response          response
     * @param responseCookie    responseCookie
     */
    public static void addCookie(HttpServletResponse response , ResponseCookie responseCookie){
        if (responseCookie!=null){
            response.addHeader(ResponseCookie.SET_COOKIE,responseCookie.toString());
        }
    }

    /**
     * 增加cookie
     * @param response          response
     * @param responseCookie    responseCookie list
     */
    public static void addCookie(HttpServletResponse response , List<ResponseCookie> responseCookie){
        if (ObjectUtil.isNotEmpty(responseCookie)){
            responseCookie.forEach(c->{
                if (c!=null){
                    response.addHeader(ResponseCookie.SET_COOKIE,c.toString());
                }
            });
        }
    }

    /**
     * 添加Cookie（使用默认参数：根路径、非安全、支持HTTP-only）
     *
     * @param response HttpServletResponse
     * @param name     Cookie名称
     * @param value    Cookie值（自动UTF-8编码）
     */
    public static void addCookie(HttpServletResponse response, String name, String value) {
        addCookie(response, name, value, -1, "/", null, false, true);
    }

    /**
     * 添加带过期时间的Cookie
     *
     * @param response HttpServletResponse
     * @param name     Cookie名称
     * @param value    Cookie值
     * @param maxAge   有效期（秒），-1表示会话期
     */
    public static void addCookie(HttpServletResponse response, String name, String value, int maxAge) {
        addCookie(response, name, value, maxAge, "/", null, false, true);
    }

    /**
     * 完整参数添加Cookie
     *
     * @param response HttpServletResponse
     * @param name     Cookie名称
     * @param value    Cookie值（自动编码）
     * @param maxAge   有效期
     * @param path     路径
     * @param domain   域名
     * @param secure   是否仅HTTPS
     * @param httpOnly 是否禁止JS访问
     */
    public static void addCookie(HttpServletResponse response,
                                 String name,
                                 String value,
                                 int maxAge,
                                 String path,
                                 String domain,
                                 boolean secure,
                                 boolean httpOnly) {
        try {
            String encodedValue = URLEncoder.encode(value, StandardCharsets.UTF_8.name());
            Cookie cookie = new Cookie(name, encodedValue);
            cookie.setMaxAge(maxAge);
            cookie.setPath(path);
            if (ObjectUtil.isNotEmpty(domain)) {
                cookie.setDomain(domain);
            }
            cookie.setSecure(secure);
            cookie.setHttpOnly(httpOnly);
            response.addCookie(cookie);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("UTF-8编码不可用", e);
        }
    }

    /**
     * 删除指定名称的所有Cookie（遍历请求中的Cookie并逐个过期）
     *
     * @param request  HttpServletRequest
     * @param response HttpServletResponse
     * @param name     要删除的Cookie名称
     */
    public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String name) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(name)) {
                    createExpiredCookie(response, cookie.getName(), cookie.getPath(), cookie.getDomain());
                }
            }
        }
    }

    /**
     * 创建立即过期的Cookie
     *
     * @param response HttpServletResponse
     * @param name     Cookie名称
     * @param path     路径（必须与原Cookie一致）
     * @param domain   域名（可为空）
     */
    private static void createExpiredCookie(HttpServletResponse response, String name, String path, String domain) {
        Cookie cookie = new Cookie(name, "");
        cookie.setMaxAge(0); // 立即过期
        cookie.setPath(ObjectUtil.isEmpty(path)?"/":path);
        if (ObjectUtil.isNotEmpty(domain)) {
            cookie.setDomain(domain);
        }
        response.addCookie(cookie);
    }
}